//*************************************************************************************
//* 作    者： 邹杭特
//* 创建时间： 2021-12-17 17:36:48
//* 描    述： 玩家数据管理（1个group一张表,同时整体可以打包成一个字符串）

//* ************************************************************************************
using UFrame;
using UFrame.DataStore;
using UFrame.DataPack;
using UnityEngine;
using System.Collections.Generic;

public class UserDataAgent<T> : AgentContext<UserDataAgent<T>, T>, IRegistAble, ILateUpdate where T : UserDataController
{
    private DataCtrl m_dataCtrl;
    private DataStoreCtrl m_dataStoreCtrl;
    public bool Runing => true;
    public float Interval => 10;
    public static string UserId { get; private set; }
    private HashSet<int> m_changedGroups;
    private string m_groupKey = "user_{0}_{1}";
    private HashSet<int> m_loadedGroups;
    protected override object ManageBody => this;

    public UserDataAgent()
    {
        m_dataStoreCtrl = new DataStoreCtrl();
        m_changedGroups = new HashSet<int>();
        m_loadedGroups = new HashSet<int>();
    }

    public void OnRegist()
    {
        m_dataStoreCtrl.OnRegist();
        m_dataCtrl = Instance.GetDataCtrl();
        m_dataCtrl.dataChangeEvent += OnDataChanged;
    }

    public void OnUnRegist()
    {
        ApplyChanges();
        m_dataStoreCtrl.OnUnRegist();
    }

    public static void LoadUserData(string userId = null)
    {
        if (UserId != userId)
        {
            UserId = userId;
            Context.ResetState();
        }
        Context.StartLoadInternal();
    }

    internal void StartLoadInternal()
    {
        Instance.CollectGroup(m_loadedGroups);
        MakeSureGroupDataLoad();
    }

    private void ResetState()
    {
        if(m_loadedGroups.Count > 0)
        {
            OnLateUpdate();
            m_changedGroups.Clear();
            m_loadedGroups.Clear();
        }
    }

    private void OnDataChanged(int groupId, int id)
    {
        m_changedGroups.Add(groupId);
    }

    private void ApplyChanges()
    {
        if (m_changedGroups.Count > 0)
        {
            foreach (var groupId in m_changedGroups)
            {
                var dataKey = string.Format(m_groupKey, UserId, groupId);

                if (m_dataCtrl.TryCollectGroup(groupId, out var groupInfo))
                {
                    m_dataStoreCtrl.SetString(dataKey, UnityEngine.JsonUtility.ToJson(groupInfo));
                }
                else
                {
                    m_dataStoreCtrl.SetString(dataKey, null);
                }
                Debug.LogError(dataKey + ":" + UnityEngine.JsonUtility.ToJson(groupInfo));

            }
            m_changedGroups.Clear();
        }
    }

    public void OnLateUpdate()
    {
        ApplyChanges();
    }

    private void MakeSureGroupDataLoad()
    {
        List<DataInfoGroup> dataGroups = new List<DataInfoGroup>();
        foreach (var groupId in m_loadedGroups)
        {
            var dataKey = string.Format(m_groupKey, UserId, groupId);
            var groupData = m_dataStoreCtrl.GetString(dataKey);
            if (!string.IsNullOrEmpty(groupData))
            {
                DataInfoGroup group = UnityEngine.JsonUtility.FromJson<DataInfoGroup>(groupData);
                if (group != null)
                {
                    group.groupId = groupId;
                    dataGroups.Add(group);
                    m_loadedGroups.Add(groupId);
                }
            }
        }
        m_dataCtrl.CopyFrom(dataGroups, true);
    }
}
